package cn.com.dhcc.turbo.service.registry;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import cn.com.dhcc.app.core.base.IocBean;
import cn.com.dhcc.app.core.exception.NiceException;
import cn.com.dhcc.app.core.exception.ServiceException;
import cn.com.dhcc.app.core.service.Log;
import cn.com.dhcc.app.core.service.Log.LOGTYPE;
import cn.com.dhcc.app.core.tag.CommonStaticCode.SUCCESSFAIL;
import cn.com.dhcc.app.core.util.JsonUtil;
import cn.com.dhcc.app.core.util.Status;
import cn.com.dhcc.app.pub.core.consts.AppIocBean;
import cn.com.dhcc.app.pub.core.consts.NodeInfoParam;
import cn.com.dhcc.turbo.entity.exch.ExchRel;
import cn.com.dhcc.turbo.entity.exch.ExchRelPipeline;
import cn.com.dhcc.turbo.entity.registry.AdapterInfo;
import cn.com.dhcc.turbo.entity.registry.NodeInfo;
import cn.com.dhcc.turbo.entity.registry.NodePipeline;
import cn.com.dhcc.turbo.entity.registry.SynchronizeInfo;
import cn.com.dhcc.turbo.entity.registry.SynchronizeInfo.SyncType;
import cn.com.dhcc.turbo.entity.sysmgr.UserInfo;
import cn.com.dhcc.turbo.service.exch.ExchRelService;
import cn.com.dhcc.turbo.service.exch.exhmgr.FtpUserService;
import cn.com.dhcc.turbo.service.queue.QueueService;
import cn.com.dhcc.turbo.service.queue.tlq.TlqOptService;
import cn.com.dhcc.turbo.service.registry.sync.ISyncSender;
import cn.com.dhcc.turbo.service.registry.sync.SyncCallBack;
import cn.com.dhcc.turbo.service.registry.sync.SynchronizeHandler;
import cn.com.dhcc.turbo.service.sysmgr.UserMgrService;
import cn.com.dhcc.turbo.service.transport.FtpService;

/**
 * 平台基础配置后续的操作
 * @author qiao
 * @2014-5-30 @上午10:07:06
 */
@Service
public class LocalConfCallBack {
	@Autowired
	SynchronizeHandler synchronizeHandler;

	
	@Autowired
	FtpUserService ftpUserService;
	@Autowired
	FtpService ftpService;
	@Autowired
	NodeInfoService nodeInfoService;
	@Autowired
	TlqOptService tlqOptService;
	@Autowired
	@Qualifier(IocBean.TLQ_QUEUE_SERVICE_BEAN)
	QueueService queueService;
	@Autowired
	UserMgrService userMgrService;
	@Autowired
	NodePipelineService nodePipelineService;
	@Autowired
	@Qualifier(AppIocBean.SYNC_SENDER_RMI_IMPL)
	ISyncSender syncSender;
	@Autowired
	ExchRelService exchRelService;
	@SuppressWarnings("deprecation")
	private static Logger logger = Log.getExistLogger(LOGTYPE.SYS);
	/**
	 * 当节点注册后执行
	 * @param nodeInfo
	 */
	public void onNodeRegist(NodeInfo nodeInfo){
		
	}
	/**
	 * 当节点删除后
	 * @param nodeInfo
	 */
	public void onNodeRemove(NodeInfo nodeInfo){
		
	}
	/**
	 * 当节点修改后
	 * @param nodeInfo
	 */
	public void onNodeUpdate(NodeInfo nodeInfo){
		
	}
	/**
	 * 在本地节点初始化之后
	 * @param localNode
	 * @throws NiceException 
	 * @throws ServiceException
	 */
	public void onLocalNodeInit(NodeInfo localNode) throws ServiceException, NiceException{
		    System.out.println("----------注册节点后更新通道信息start-----------"+localNode);
			nodePipelineService.updateNodePipeLineOwner(localNode);
			System.out.println("----------注册节点后更新通道信息end-----------");
			//初始化成功后对超级管理员,通道重新设置
			UserInfo user = userMgrService.getUserByUserName(NodeInfoParam.ADMIN_USERNAME);
			user.setOwnId(localNode.getId());
			userMgrService.insertOrUpdateUser(user);
			
	}
	/**
	 * 当交换关系建立后的资源分配
	 * @param localNode 本地节点
	 * @param remoteNode 加入交换关系的远程节点
	 * @throws ServiceException
	 * @throws NiceException 
	 */
	public void onNodeExchRelCreate(NodeInfo localNode ,NodeInfo remoteNode) throws ServiceException, NiceException{
		//分配队列
		Status status =  queueService.initSendQueue(remoteNode);
		if(!status.isSuccess()){
			throw new NiceException("交换关系建立成功，但消息队列分配失败,请在TonglinkQ资源分配界面手动处理！");
		}
	}
	
	/**
	 * 通道调用远程接口获取fromNode 和 toNode，也就是交换关系的双方的通道信息，主要是tlq信息
	 * @param fromNode
	 * @param toNode
	 * @return
	 * @throws ServiceException 
	 */
	public Status getPipelineInfo(NodeInfo fromNode,NodeInfo toNode) throws ServiceException{
		Status status=Status.getInstance();
		NodeInfo localNode = nodeInfoService.getLocalNode();
		//现获取fromNode的通道信息
		ExchRelPipeline exchPipeline=new ExchRelPipeline(fromNode, toNode, fromNode);
		NodePipeline fromPipeline=null;
		NodePipeline toPieline=null;
		SynchronizeInfo pipelineInfo = new SynchronizeInfo();
		pipelineInfo.setDataType(SyncType.REL_PIPE_LINE.getCode());
		pipelineInfo.setDataContent(JsonUtil.toJson(exchPipeline));
		SyncCallBack syncCallBack = null;
		if (fromNode.getId().equalsIgnoreCase(localNode.getId())) {//如果fromNode是当前节点,则直接从当前节点获取通道信息
			fromPipeline=synchronizeHandler.getPipleLineInfo(toNode.getNodeCode());//以toNode查找负载的通道
		}else{//通道远程接口返回
			pipelineInfo.setFromNodeInfo(localNode);
			pipelineInfo.setToNodeInfo(fromNode);
			pipelineInfo.setSrcNodeInfo(fromNode);
			try {
				syncCallBack = syncSender.sendData(fromNode.getInstallUrl(),pipelineInfo);
				if(syncCallBack.getResult()==SUCCESSFAIL.FAIL){//如果目的节点关系数据保存失败，则整个关系建立失败
					status.setSuccess(false);
					status.setMsg(syncCallBack.getMsg());
					return status;
				}else{//如果成功表示获取系fromNode的通道信息成功
					fromPipeline=(NodePipeline) syncCallBack.getNodePipeline();
				}
			} catch (Exception e) {
				logger.error(e);
				status.setSuccess(false);
				status.setMsg(e.getMessage());
				return status;
			}
		}
		exchPipeline.setFromPipeline(fromPipeline);
		
		//读取toNode的通道信息
		if (toNode.getId().equalsIgnoreCase(localNode.getId())) {//如果toNode是当前节点,则直接从当前节点获取通道信息
			toPieline=synchronizeHandler.getPipleLineInfo(fromNode.getNodeCode());//以toNode查找负载的通道
		}else{//通道远程接口返回
			pipelineInfo.setFromNodeInfo(localNode);
			pipelineInfo.setToNodeInfo(toNode);
			pipelineInfo.setSrcNodeInfo(toNode);
			exchPipeline.setNeed(toNode);//现在需要toNode的通道信息
			pipelineInfo.setDataContent(JsonUtil.toJson(exchPipeline));
			try {
				syncCallBack = syncSender.sendData(toNode.getInstallUrl(),pipelineInfo);
				if(syncCallBack.getResult()==SUCCESSFAIL.FAIL){//如果目的节点关系数据保存失败，则整个关系建立失败
					status.setSuccess(false);
					status.setMsg(syncCallBack.getMsg());
					return status;
				}else{//如果成功表示获取系fromNode的通道信息成功
					toPieline=(NodePipeline) syncCallBack.getNodePipeline();
				}
			} catch (Exception e) {
				logger.error(e);
				status.setSuccess(false);
				status.setMsg(e.getMessage());
				return status;
			}
		}
		exchPipeline.setToPipeline(toPieline);
		
		
		//再通知fromNode
		if (fromNode.getId().equalsIgnoreCase(localNode.getId())) {//如果fromNode是当前节点,则直接保存对方的通道信息
			synchronizeHandler.updatePipeline(exchPipeline.getToPipeline());//更新fromNode通道信息
		}else{
			try {
				
				pipelineInfo.setFromNodeInfo(localNode);
				pipelineInfo.setToNodeInfo(fromNode);
				pipelineInfo.setSrcNodeInfo(fromNode);
				exchPipeline.setNeed(null);//现在需要toNode的通道信息
				pipelineInfo.setDataContent(JsonUtil.toJson(exchPipeline));
				syncCallBack = syncSender.sendData(fromNode.getInstallUrl(),pipelineInfo);
				if(syncCallBack.getResult()==SUCCESSFAIL.FAIL){//如果目的节点关系数据保存失败，则整个关系建立失败
					status.setSuccess(false);
					status.setMsg(syncCallBack.getMsg());
					return status;
				}
			} catch (Exception e) {
				logger.error(e);
				status.setSuccess(false);
				status.setMsg(e.getMessage());
				return status;
			}
		}
		
		status.setSuccess(true);
		status.setMsg("获取通道信息成功");
		return status;
		
	}
	public Status beforeCreateRel(ExchRel exchRel ) {
		String fromNodeId = exchRel.getNodeIdCreator();
		String toNodeId = exchRel.getNodeIdTo();
		NodeInfo fromNode = null;
		NodeInfo toNodeInfo = null;
		NodeInfo localNode = null;
		Status createRelResult = new Status();
		Status statusFromNode = null; 
		String msg = "";
		try {
			fromNode = nodeInfoService.get(fromNodeId);
			toNodeInfo = nodeInfoService.get(toNodeId);
			localNode = nodeInfoService.getLocalNode();
		} catch (ServiceException e) {
			createRelResult.setSuccess(false);
			createRelResult.setMsg("系统异常，请联系管理员！");
			return createRelResult;
		}
		//判断是否是和本地节点有关的交换关系
		boolean fromLocal = false;
		NodeInfo remoteNode = toNodeInfo;
		
		if(fromNode.getId().equalsIgnoreCase(localNode.getId())){
			fromLocal = true;
			remoteNode = toNodeInfo;
		}
		if(toNodeInfo.getId().equalsIgnoreCase(localNode.getId())){
			fromLocal = true;
			remoteNode = fromNode;
		}
		
		
		//建立交换关系前，先获取fromNode和toNode的通道信息
		//现获取fromNode的通道信息
//		ExchRelPipeline exchPipeline=null;
		//
		try {
			Status status=this.getPipelineInfo(fromNode, toNodeInfo);
			if (status.isSuccess()) {
//				exchPipeline=(ExchRelPipeline) status.getData();
			}else{
				createRelResult.setSuccess(false);
				createRelResult.setMsg("交换关系创建失败,"+status.getMsg());
				return createRelResult;
			}
		} catch (ServiceException e1) {
			createRelResult.setSuccess(false);
			createRelResult.setMsg("交换关系创建失败,"+e1.getMessage());
			return createRelResult;
		}
		
		
		//判断结束
		
		
		
		
		
		//发起一个命令让远程节点去建立交换关系,只有成功了才进行另外的操作
		SyncCallBack syncCallBack = null;
		SynchronizeInfo synchronizeInfo = new SynchronizeInfo();
		synchronizeInfo.setDataType(SyncType.CREATE_REL.getCode());
		synchronizeInfo.setDataContent(JsonUtil.toJson(exchRel));
		synchronizeInfo.setFromNodeInfo(localNode);
		synchronizeInfo.setToNodeInfo(remoteNode);
		synchronizeInfo.setSrcNodeInfo(toNodeInfo);
		try {
			syncCallBack = syncSender.sendData(remoteNode.getInstallUrl(),synchronizeInfo);
			if(syncCallBack.getResult()==SUCCESSFAIL.FAIL){//如果目的节点关系数据保存失败，则整个关系建立失败
				createRelResult.setSuccess(false);
				createRelResult.setMsg("交换关系创建失败,节点["+remoteNode.getNodeName()+"]接收数据异常！");
				return createRelResult;
			}
		} catch (Exception e) {
			logger.error(e);
			createRelResult.setSuccess(false);
			createRelResult.setMsg("交换关系创建失败！");
			return createRelResult;
		}
		
		
		//开始处理另外一个节点
		if(syncCallBack.getResult()==SUCCESSFAIL.SUCCESS){//如果目的节点关系数据已保存成功
			boolean createTlqStatus = (Boolean) syncCallBack.getStatus();
			if(createTlqStatus==false){//通道建立失败，关系可以建立
				msg += "|★从节点["+remoteNode.getNodeName()+"]到节点["+fromNode.getNodeName()+"]的消息队列建立失败，请在"+remoteNode.getNodeName()+"管理界面手动创建！";
			}
			if(fromLocal){
				//如果是和本地建立关系，则只需要在本地创建队列
				statusFromNode =  queueService.initSendQueue(remoteNode);
				if(!statusFromNode.isSuccess()){
					msg += "|★从节点["+localNode.getNodeName()+"]到节点["+remoteNode.getNodeName()+"]的消息队列建立失败，请在"+localNode.getNodeName()+"管理界面手动创建！";
				}
			}else{
				try {
					syncCallBack = syncSender.sendData(fromNode.getInstallUrl(),synchronizeInfo);
				} catch (Exception e) {
					logger.error(e);
					createRelResult.setSuccess(false);
					createRelResult.setMsg("交换关系创建失败！");
					return createRelResult;
				}
				if(syncCallBack.getResult()==SUCCESSFAIL.FAIL){//如果节点关系数据保存失败，则整个关系建立失败
					createRelResult.setSuccess(false);
					createRelResult.setMsg("交换关系创建失败,节点["+fromNode.getNodeName()+"]接收数据异常！");
					return createRelResult;
				}else{
					boolean createTlqStatus2 = (Boolean) syncCallBack.getStatus();
					if(createTlqStatus2==false){//通道建立失败，关系可以建立
						msg += "|★从节点["+fromNode.getNodeName()+"]到节点["+remoteNode.getNodeName()+"]的消息队列建立失败，请在"+fromNode.getNodeName()+"管理界面手动创建！";
					}
				}
			}
			//两步都成功了
			createRelResult.setSuccess(true);
			if(StringUtils.hasText(msg)){
				createRelResult.setMsg("交换关系建立成功，但出现以下异常：|"+msg);
			}else{
				createRelResult.setMsg("交换关系建立成功！");
			}
			return createRelResult;
		}
		createRelResult.setSuccess(false);
		createRelResult.setMsg("交换关系创建失败！");
		return createRelResult;
	}
	/**
	 * 当从本地删除一个交换关系（节点）的已分配资源处理
	 * @param remoteNode 删除的交换关系（节点）
	 * @throws ServiceException
	 */
	public Status onNodeExchRelRemove(NodeInfo fromNode ,NodeInfo toNode) throws ServiceException{
		NodeInfo localNode = null;
		Status createRelResult = new Status();
		try {
			localNode = nodeInfoService.getLocalNode();
		} catch (ServiceException e) {
			createRelResult.setSuccess(false);
			createRelResult.setMsg("系统异常，请联系管理员！");
			return createRelResult;
		}
		//判断是否是和本地节点有关的交换关系
		boolean fromLocal = false;
		NodeInfo remoteNode = toNode;
		
		if(fromNode.getId().equalsIgnoreCase(localNode.getId())){
			fromLocal = true;
			remoteNode = toNode;
		}
		if(toNode.getId().equalsIgnoreCase(localNode.getId())){
			fromLocal = true;
			remoteNode = fromNode;
		}
		//判断结束
		
		//发起一个命令让远程节点去建立交换关系,只有成功了才进行另外的操作
		SyncCallBack syncCallBack = null;
		SynchronizeInfo synchronizeInfo = new SynchronizeInfo();
		synchronizeInfo.setDataType(SyncType.DELEE_REL.getCode());
		ExchRel exchRel = new ExchRel();
		exchRel.setNodeIdCreator(remoteNode.getId());
		exchRel.setNodeIdTo(fromNode.getId());
		synchronizeInfo.setDataContent(JsonUtil.toJson(exchRel));
		synchronizeInfo.setFromNodeInfo(localNode);
		synchronizeInfo.setToNodeInfo(remoteNode);
		synchronizeInfo.setSrcNodeInfo(toNode);
		try {
			syncCallBack = syncSender.sendData(remoteNode.getInstallUrl(),synchronizeInfo);
			if(syncCallBack.getResult()==SUCCESSFAIL.FAIL){//如果目的节点关系数据保存失败，则整个关系建立失败
				createRelResult.setSuccess(false);
				createRelResult.setMsg("交换关系删除失败,节点["+remoteNode.getNodeName()+"]接收数据异常！");
				return createRelResult;
			}
		} catch (Exception e) {
			logger.error(e);
			createRelResult.setSuccess(false);
			createRelResult.setMsg("交换关系删除失败！");
			return createRelResult;
		}
		
		
		//开始处理另外一个节点
		if(syncCallBack.getResult()==SUCCESSFAIL.SUCCESS){//如果目的节点关系数据已保存成功
			if(fromLocal){
				
			}else{
				synchronizeInfo = new SynchronizeInfo();
				synchronizeInfo.setDataType(SyncType.DELEE_REL.getCode());
				exchRel = new ExchRel();
				exchRel.setNodeIdCreator(remoteNode.getId());
				exchRel.setNodeIdTo(fromNode.getId());
				synchronizeInfo.setDataContent(JsonUtil.toJson(exchRel));
				synchronizeInfo.setFromNodeInfo(localNode);
				synchronizeInfo.setToNodeInfo(fromNode);
				synchronizeInfo.setSrcNodeInfo(localNode);
				try {
					syncCallBack = syncSender.sendData(fromNode.getInstallUrl(),synchronizeInfo);
					if(syncCallBack.getResult()==SUCCESSFAIL.FAIL){//如果目的节点关系数据保存失败，则整个关系建立失败
						createRelResult.setSuccess(false);
						createRelResult.setMsg("交换关系删除失败,节点["+fromNode.getNodeName()+"]接收数据异常！");
						return createRelResult;
					}
				} catch (Exception e) {
					logger.error(e);
					createRelResult.setSuccess(false);
					createRelResult.setMsg("交换关系删除失败！");
					return createRelResult;
				}
			}
			exchRelService.delete(fromNode.getId(), toNode.getId());
			//两步都成功了
			createRelResult.setSuccess(true);
			createRelResult.setMsg("交换关系删除成功！");
			return createRelResult;
		}
		createRelResult.setSuccess(false);
		createRelResult.setMsg("交换关系删除失败！");
		return createRelResult;
		
	}
	
	
	/**
	 * 当系统接入本地节点后的资源分配处理
	 * @param sysInfo 接入的系统
	 * @throws ServiceException
	 */
	public void onAdapterRegist(AdapterInfo adapterInfo) throws ServiceException{
		//创建ftp用户
		ftpUserService.createAdapterUser(adapterInfo);
		//创建登录用户
		userMgrService.createAdapterUser(adapterInfo);
	}
	/**
	 * 当本地节点删除一个接入的系统的已分配资源处理
	 * @param sysInfo 删除的系统
	 * @throws ServiceException
	 */
	public void onAdapterRemove(AdapterInfo adapterInfo) throws ServiceException{
		//删除Ftp用户
		ftpUserService.deleteFtpUserByAdapterCode(adapterInfo.getAdapterCode());
		//删除登录用户
		userMgrService.deleteAdapterUser(adapterInfo);
	}
}
